package SystemB;

/******************************************************************************************************************
* File:SmokeDetector.java
* Course: 17655
* Project: Assignment A3
* Copyright: Copyright (c) 2013 Carnegie Mellon University
* Versions:
*	1.0 March 2013 - luisrocha
*
* Description:
*
* This class simulates a smoke detector and allows to issue smoke events to simulate
*
* Parameters: IP address of the event manager (on command line). If blank, it is assumed that the event manager is
* on the local machine.
*
* Internal Methods:
*	float GetRandomNumber()
*	boolean CoinToss()
*   void PostHumidity(EventManagerInterface ei, float humidity )
*
******************************************************************************************************************/
import EventPackage.*;
import InstrumentationPackage.*;

class SmokeDetector
{
		
	public static void main(String args[])
	{
                String EvtMgrIP;					// Event Manager IP address
		Event Evt = null;					// Event object
		EventQueue eq = null;				// Message Queue
		int EvtId = 0;						// User specified event ID
		EventManagerInterface em = null;	// Interface object to the event manager
		boolean SmokeDetectorState = false; // Smoke Detector state: false == no smoke, true == smoke
                int counter = 0;
                boolean SprinklerState = false;	// Sprinkler state: false == off, true == on
		int	Delay = 2500;					// The loop delay (2.5 seconds)
		boolean Done = false;				// Loop termination flag


		
		/////////////////////////////////////////////////////////////////////////////////
		// Get the IP address of the event manager
		/////////////////////////////////////////////////////////////////////////////////

 		if ( args.length == 0 )
 		{
			// event manager is on the local system

			System.out.println("\n\nAttempting to register on the local machine..." );

			try
			{
				// Here we create an event manager interface object. This assumes
				// that the event manager is on the local machine

				em = new EventManagerInterface();
			}

			catch (Exception e)
			{
				System.out.println("Error instantiating event manager interface: " + e);

			} // catch

		} else {

			// event manager is not on the local system

			EvtMgrIP = args[0];

			System.out.println("\n\nAttempting to register on the machine:: " + EvtMgrIP );

			try
			{
				// Here we create an event manager interface object. This assumes
				// that the event manager is NOT on the local machine

				em = new EventManagerInterface( EvtMgrIP );
			}

			catch (Exception e)
			{
				System.out.println("Error instantiating event manager interface: " + e);

			} // catch

		} // if

		// Here we check to see if registration worked. If ef is null then the
		// event manager interface was not properly created.

		if (em != null)
		{

			// We create a message window. Note that we place this panel about 1/2 across 
			// and 2/3s down the screen
			
			float WinPosX = 0.5f; 	//This is the X position of the message window in terms 
									//of a percentage of the screen height
			float WinPosY = 0.75f;	//This is the Y position of the message window in terms 
								 	//of a percentage of the screen height 
			
			MessageWindow mw = new MessageWindow("Smoke Detector", WinPosX, WinPosY);

			mw.WriteMessage("Registered with the event manager." );

                    try
                    {
				mw.WriteMessage("   Participant id: " + em.GetMyId() );
				mw.WriteMessage("   Registration Time: " + em.GetRegistrationTime() );

 			} // try

                    catch (Exception e)
                    {
			mw.WriteMessage("Error:: " + e);

                    } // catch

                    /********************************************************************
                    ** Here we start the main simulation loop
                    *********************************************************************/

                    mw.WriteMessage("Beginning Smoke Simulation... smoke turns on every 30s");

                    while ( !Done )
                    {
                        // Post a smoke event every 30 seconds. if the smoke event is true keep
                        // sending it until it is false (sprinkler activates)
                        if ( counter >= 30000/Delay ) //12 to count 30s waiting 2.5s per while loop
                        {
                            if ((!SprinklerState) && (!SmokeDetectorState)) // do not turn smoke detector on while sprinkler is on
                            {
                                SmokeDetectorState = true;
                                PostSmoke( em, SmokeDetectorState);
                                mw.WriteMessage("Current Smoke State:: " + SmokeDetectorState);
                                counter = 0;
                            } //if
          
                        } //if
                        else 
                        {
                            counter ++;               // count up towards the 30s time     
                            mw.WriteMessage(((30000-counter*Delay)/1000) + "s until next smoke event");
                                                      
                        }
                        
 

                        // Get the message queue

                        try
                        {
                                eq = em.GetEventQueue();

                        } // try

                        catch( Exception e )
                        {
                                mw.WriteMessage("Error getting event queue::" + e );

                        } // catch

                        // If there are messages in the queue, we read through them.
                        // We are looking for EventIDs = -11, this means the the sprinkler or
                        // has been turned on/off. Note that we get all the messages
                        // from the queue at once... there is a 2.5 second delay between samples,..
                        // so the assumption is that there should only be a message at most.
                        // If there are more, it is the last message that will effect the
                        // output of the humidity as it would in reality.

                        int qlen = eq.GetSize();

                        for ( int i = 0; i < qlen; i++ )
                        {
                                Evt = eq.GetEvent();

                                if ( Evt.GetEventId() == -11 )
                                {
                                        if (Evt.GetMessage().equalsIgnoreCase("S1")) // Sprinkler on
                                        {
                                                SprinklerState = true;
                                                SmokeDetectorState = false;
                                                mw.WriteMessage("Sprinkler on. Current Smoke State:: " + SmokeDetectorState);
                                                PostSmoke( em, SmokeDetectorState);
                                                counter = 0;
                                                
                                        } // if

                                        if (Evt.GetMessage().equalsIgnoreCase("S0")) // Sprinkler off
                                        {
                                                SprinklerState = false;
                                                mw.WriteMessage("Sprinkler off. Current Smoke State:: " + SmokeDetectorState);
                                                //counter = 0;

                                        } // if

                                } // if
                                
                                if ( Evt.GetEventId() == -10 )  // fire alarm events
                                {
                                        if (Evt.GetMessage().equalsIgnoreCase("F1")) // Fire Alarm on
                                        {
                                                // nothing to do
                                                
                                        } // if

                                        if (Evt.GetMessage().equalsIgnoreCase("F0")) // Fire Alarm off
                                        {
                                                SmokeDetectorState = false;
                                                mw.WriteMessage("Fire Alarm off. Reset smoke stake. Current Smoke State:: " + SmokeDetectorState);
                                                counter = 0;

                                        } // if

                                } // if

                                // If the event ID == 99 then this is a signal that the simulation
                                // is to end. At this point, the loop termination flag is set to
                                // true and this process unregisters from the event manager.

                                if ( Evt.GetEventId() == 99 )
                                {
                                        Done = true;

                                        try
                                        {
                                                em.UnRegister();

                                } // try

                                catch (Exception e)
                                {
                                                mw.WriteMessage("Error unregistering: " + e);

                                } // catch

                                mw.WriteMessage("\n\nSimulation Stopped. \n");

                                } // if

                        } // for

                        // Here we wait for a 2.5 seconds before we start the next sample

                        try
                        {
                            //sleep
                            Thread.sleep( Delay );

                        } // try

                        catch( Exception e )
                        {
                                mw.WriteMessage("Sleep error:: " + e );

                        } // catch

                    } // while

                } else {

			System.out.println("Unable to register with the event manager.\n\n" );

		} // if

	} // main


	/***************************************************************************
	* CONCRETE METHOD:: PostSmoke
	* Purpose: This method posts if there is smoke or not to the
	* specified event manager. This method assumes an event ID of 10.
	*
	* Arguments: EventManagerInterface ei - this is the eventmanger interface
	*			 where the event will be posted.
	*
	*			 boolean smokeState - this is true if there is smoke
	*
	* Returns: none
	*
	* Exceptions: None
	*
	***************************************************************************/

	static private void PostSmoke(EventManagerInterface ei, boolean smokeState )
	{
		// Here we create the event.

		Event evt = new Event( (int) 10, String.valueOf(smokeState) );

		// Here we send the event to the event manager.

		try
		{
			ei.SendEvent( evt );
			//mw.WriteMessage( "Sent Smoke Event" );

		} // try

		catch (Exception e)
		{
			System.out.println( "Error Posting Smoke:: " + e );

		} // catch

	} // PostSmoke

} // SmokeDetector